<template>
  <div>
    <el-card style="margin: 20px 0" shadow="hover">
      <el-form label-width="100px">
        <el-form-item label="SPU名称">
          <el-input placeholder="SPU名称" v-model="formData.spuName"></el-input>
        </el-form-item>
        <el-form-item label="品牌">
          <el-select v-model="tmId"
            ><!-- 若v-model绑formData.tmId,获取到的值是number类型,所以定义一个tmId变量转换成string类型 -->
            <el-option
              v-for="tm in trademarks"
              :key="tm.id"
              :label="tm.tmName"
              :value="tm.id"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="SPU描述">
          <el-input
            type="textarea"
            rows="4"
            placeholder="SPU描述"
            v-model="formData.description"
          ></el-input>
        </el-form-item>
        <el-form-item label="SPU图片">
          <el-upload
            class="avatar-uploader"
            :action="uploadURL"
            list-type="picture-card"
            v-model:file-list="fileList"
            :on-preview="onPreviewHandler"
          >
            <el-icon class="avatar-uploader-icon"><ele-Plus /></el-icon>
          </el-upload>
        </el-form-item>
        <el-form-item label="销售属性">
          <el-select
            v-model="baseSaleAttr"
            :placeholder="`还有 ${unusedBaseSaleAttrs.length} 未选择`"
          >
            <el-option
              v-for="item in unusedBaseSaleAttrs"
              :key="item.id"
              :value="item.id + ',' + item.name"
              :label="item.name"
            ></el-option>
          </el-select>
          <el-button
            type="primary"
            style="margin-left: 20px"
            :disabled="!baseSaleAttr"
            @click="baseSaleAttrChangeHandler"
            >添加销售属性</el-button
          >
        </el-form-item>
        <el-form-item>
          <el-table border stripe :data="formData.spuSaleAttrList">
            <el-table-column
              label="序号"
              width="100"
              header-align="center"
              type="index"
            ></el-table-column>
            <el-table-column
              label="属性名"
              header-align="center"
              prop="saleAttrName"
            ></el-table-column>
            <el-table-column label="属性值名称列表" header-align="center">
              <template #="{ row }">
                <!-- 显示已经存在的值的列表 -->
                <el-tag
                  style="margin-right: 5px"
                  v-for="item in row.spuSaleAttrValueList"
                  :key="item.saleAttrValueName"
                  closable
                  @close="deleteSaleAttrValueNameHandler(row, item)"
                  >{{ item.saleAttrValueName }}</el-tag
                >
                <el-input
                  style="width: 100px"
                  v-if="row.isEdit"
                  ref="saleAttrValueNameRef"
                  v-model="newSaveSaleAttrValueName"
                  @blur="saveSaleAttrValueNameHandler(row)"
                  @keydown.enter="saveSaleAttrValueNameHandler(row)"
                ></el-input>
                <el-button
                  v-else
                  @click="changeSaleAttrValueNameEditStatusHandler(row)"
                  >添加</el-button
                >
              </template>
            </el-table-column>
            <el-table-column label="操作" header-align="center">
              <template #="{ row }">
                <el-button
                  type="danger"
                  icon="ele-Delete"
                  @click="deleteSaleAttrHandler(row)"
                ></el-button>
              </template>
            </el-table-column>
          </el-table>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="saveSpuInfo">保存</el-button>
          <el-button @click="$emit('change-view', ViewNames.LIST)"
            >取消</el-button
          >
        </el-form-item>
      </el-form>
    </el-card>
    <!-- 预览图片的对话框 -->
    <el-dialog
      v-model="isShowPreviewImageDialog"
      :title="previewImg?.name"
      @close="closeDialogHandler"
    >
      <img
        :src="previewImg?.url"
        style="width: 100%; max-height: calc(100vh - 200px)"
      />
    </el-dialog>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, computed, nextTick, toRaw } from "vue";
export default defineComponent({
  name: "SpuForm",
});
</script>
<script lang="ts" setup>
import type {
  typeSaveSpuInfo,
  ResBaseSaleAttr,
  spuSaleAttr,
  spuSaleAttrValue,
  ReqUpdateSpuInfo
} from "@/api/spu";
import { reqBaseSaleAttrListInfo, reqSaveSpuInfo,requestSpuSaleAttrList,requestSpuImageList } from "@/api/spu";
import type {ResSPU} from "@/api/spu"
import type { UploadFile, UploadFiles, UploadUserFile } from "element-plus";
import { ElMessage, ElMessageBox } from "element-plus";
import { requestAllTrademarkInfo } from "@/api/trademark";
import type { typeRecord } from "@/api/trademark";
import { ViewNames } from "../index";

//数据1:  收集用户数据的对象
const formData = ref<typeSaveSpuInfo|ReqUpdateSpuInfo>({
  category3Id: 0,
  spuName: "",
  tmId: 0,
  description: "",
  spuImageList: [],
  spuSaleAttrList: [],
});
//数据2:  图片上传的地址
const uploadURL = ref(`${import.meta.env.VITE_API_URL}/product/upload`);
//数据3:  upload已经上传后的所有图片
const fileList = ref<UploadUserFile[]>([]);
//数据4:  为了适应el-select的默认值，特意定义一个变量用于收集 tmId
const tmId = ref<string | number>("");
//数据5:  存储所有品牌列表
const trademarks = ref<typeRecord[]>([]);
//数据6:  基础销售属性列表
const baseSaleAttrs = ref<ResBaseSaleAttr[]>([]);
//数据7:  用户选择的基础销售属性值
const baseSaleAttr = ref("");
//数据8:  要预览显示的图片
const previewImg = ref<UploadFile | null>(null);
//数据9:  是否显示预览图片对话框
const isShowPreviewImageDialog = computed(() => !!previewImg.value);
//数据10: 销售属性值输入框实例对象
const saleAttrValueNameRef = ref(null);
//数据11: 销售属性值变量（双向绑定到了input中）
const newSaveSaleAttrValueName = ref("");
const emits = defineEmits(["change-view"]);
const props = defineProps<{
  data?: ResSPU;
}>();
//请求1:  获取所有品牌列表
const getTrademarkList = async () => {
  try {
    const result = await requestAllTrademarkInfo();
    // console.log("请求1品牌列表", result);
    trademarks.value = result;
  } catch (e) {}
};
getTrademarkList();
//请求2:  获取基础销售属性列表
const getBaseSaleAttrListInfo = async () => {
  try {
    const result = await reqBaseSaleAttrListInfo();
    baseSaleAttrs.value = result;
    // console.log("请求2销售属性列表", result);
  } catch (e) {}
};
getBaseSaleAttrListInfo();
// 如果 props.data 中存在数据，表示当前是编辑，那么就用 props.data 中的数据去初始化 formData
console.log("props",props);
if (props.data) {
  
  (formData.value as ReqUpdateSpuInfo).id = props.data.id;
  formData.value.spuName = props.data.spuName;
  formData.value.tmId = props.data.tmId;
  formData.value.description = props.data.description;
  tmId.value = props.data.tmId;

  getSpuImageList();
  getSpuSaleAttrList();
}
//请求3:  添加spu保存
const saveSpuInfo = async () => {
  try {
    if (tmId.value != "") {
      formData.value.tmId = Number(tmId.value);
    }
    // 通过 fileList 来获取upload组件已经上传成功后的所有图片
    // console.log(fileList);
    // 把 fileList 数据转成 formData所需要的格式
    formData.value.spuImageList = fileList.value.map((item) => {
      return {
        imgName: item.name,
        imgUrl: (item.response as { data: string }).data,
      };
    });
    await reqSaveSpuInfo(formData.value);
    ElMessage.success("保存成功");
    emits("change-view", ViewNames.LIST);
  } catch (e) {
    ElMessage.error("保存失败");
  }
};
// 获取指定spu下的所有图片列表
async function getSpuImageList() {
  try {
    const res = await requestSpuImageList(props.data!.id);
    // 转成upload 组件需要用到的格式
    fileList.value = res.map((item) => {
      return {
        name: item.imgName,
        // 用于组件显示
        url: item.imgUrl,
        // 用于提交的时候，数据收集使用
        response: { data: item.imgUrl },
      };
    });
  } catch (e) {}
}
// 获取当前spu已经使用过的销售属性数据
async function getSpuSaleAttrList() {
  try {
    formData.value.spuSaleAttrList = await requestSpuSaleAttrList(
      props.data!.id
    );
  } catch (e) {}
}
//方法1:  收集当前上传成功的图片
const onSuccessHandler = (
  response: any,
  uploadFile: UploadFile,
  uploadFiles: UploadFiles
) => {
  //   console.log(uploadFiles);
  //  把 uploadFiles 格式的数据转成 formData 所需要的格式
  formData.value.spuImageList = uploadFiles.map((item) => {
    return {
      imgName: item.name,
      imgUrl: (item.response as { data: string }).data,
    };
  });
};
//方法2:  上传图片预览
function onPreviewHandler(uploadFile: UploadFile) {
  previewImg.value = uploadFile;
}
//方法3:  关闭预览对话框
function closeDialogHandler() {
  previewImg.value = null;
}
//方法4:  通过 el-select 选择基础销售属性
function baseSaleAttrChangeHandler() {
  // console.log(baseSaleAttr);
  if (baseSaleAttr.value != "") {
    const [id, saleAttrName] = baseSaleAttr.value.split(",");
    // 向 formData.spuSaleAttrList 添加一条新的数据
    formData.value.spuSaleAttrList.push({
      baseSaleAttrId: Number(id),
      saleAttrName,
      spuSaleAttrValueList: [],
      isEdit: false,
    });
    // 清空用户选中的值
    baseSaleAttr.value = "";
  }
}
//方法5:  改变销售属性值编辑状态
function changeSaleAttrValueNameEditStatusHandler(row: spuSaleAttr) {
  row.isEdit = true;
  nextTick(() => {
    // @ts-ignore
    saleAttrValueNameRef.value.focus();
  });
}
//方法6:  添加销售属性
function saveSaleAttrValueNameHandler(row: spuSaleAttr) {
  console.log("newSaveSaleAttrValueName.value",newSaveSaleAttrValueName.value);
  const newValue = newSaveSaleAttrValueName.value.trim();
  // 保存之前进行一些必要的判断
  if (newValue == "") {
    ElMessage.error("值不能为空");
    // row.saleAttrName = "123123";
    // row.isEdit = false;
    // nextTick要配合render
    // nextTick(() => {
    //   console.log(123);
    //   // @ts-ignore
    //   saleAttrValueNameRef.value.focus();
    // });

    nextTick(()=>{
    console.log("saleAttrValueNameRef.value", saleAttrValueNameRef.value);

    //@ts-ignore
      saleAttrValueNameRef.value!.focus();
    })
    return;
  }
  // 判断当前已经添加的值列表中是否存在相同的内容
  const isExists = row.spuSaleAttrValueList.find(
    (item) => item.saleAttrValueName == newValue
  );
  if (isExists) {
    ElMessage.error("值不能重复");
    // row.isEdit = false;
    // 不要去设置newValue，因为 newValue 和  newSaveSaleAttrValueName  不是引用关系
    // newValue = "";
    newSaveSaleAttrValueName.value = "";
    nextTick(()=>{
    // @ts-ignore
      saleAttrValueNameRef.value!.focus();
    })
    return;
  }
  // 添加属性到指定对象（当前输入框所在这一行数据）
  const { baseSaleAttrId, saleAttrName } = row;
  row.spuSaleAttrValueList.push({
    baseSaleAttrId,
    saleAttrName,
    saleAttrValueName: newSaveSaleAttrValueName.value,
  });
  // 改变编辑状态
  row.isEdit = false;
  // 清空输入框中的内容
  newSaveSaleAttrValueName.value = "";
}

//方法7:  删除指定的销售属性值

function deleteSaleAttrValueNameHandler(
  row: spuSaleAttr,
  item: spuSaleAttrValue
) {
  // 从 row.spuSaleAttrValueList 中删除 item
  row.spuSaleAttrValueList = row.spuSaleAttrValueList.filter(
    (saleAttrValue) => saleAttrValue != item
  );
}

//方法8:   删除置顶的销售属性

async function deleteSaleAttrHandler(row: spuSaleAttr) {
  // 如果row是一个响应式的数据
  // 从 formData.value.spuSaleAttrList 删除 row
  row = toRaw(row);
  try {
    await ElMessageBox({
      title: "提示",
      message: "你确定要删除吗？",
    });
    formData.value.spuSaleAttrList = formData.value.spuSaleAttrList.filter(
      (saleAttr) => saleAttr.saleAttrName != row.saleAttrName
    );
    // console.log(formData.value.spuSaleAttrList, row);
  } catch (e) {}
}

//计算1:  计算未被使用的基础销售属性列表数据
const unusedBaseSaleAttrs = computed(() => {
  const newArr: ResBaseSaleAttr[] = [];
  // console.log("计算1baseSaleAttrs.value", baseSaleAttrs.value);

  // 循环 baseSaleAttrs，把循环过程中的每一个数据拿着和 formData.value.spuSaleAttrList 进行比较
  baseSaleAttrs.value.forEach((item) => {
    // item: {id: 1, name: 'aa'} , {id:2, name: 'bb'}
    // formData.value.spuSaleAttrList: [{baseSaleAttrId: 1}, {baseSaleAttrId:2}]
    const isUsed = formData.value.spuSaleAttrList.find((item2) => {
      return  item2.baseSaleAttrId == item.id;
    });
    // console.log("计算1:formData.value.spuSaleAttrList",formData.value.spuSaleAttrList);
    
    // console.log("计算1",item, isUsed);
    // 如果当前item没有被使用，则添加到 newArr 中
    if (!isUsed) {
      newArr.push(item);
    }
  });
  return newArr;
});
</script>

<style lang="less" scoped></style>
